﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.IO;
using dotNails.CodeGen.Util;

namespace dotNails.CodeGen.Models {
	
	[Serializable]
	public class ConfigData {
		public DotNailsConfig Config { get; set; }
		protected string _configFilePath;

		public ConfigData(string configFilePath) {
			Config = LoadConfigDataFromXml(configFilePath);
			_configFilePath = configFilePath;
		}

		public DotNailsConfig LoadConfigDataFromXml(string configFilePath) {
			XElement configXML = XElement.Load(configFilePath);
			
			// Testing
			//TestAttribute = (string)configXML.Attribute("TestAttribute");
			//TestElement = (string)configXML.Elements("TestElement").Single();
			string node = "ExcludedColumns.Column";
			DotNailsConfig dotNailsConfig = new DotNailsConfig {
				TestAttribute = (string)configXML.Attribute("TestAttribute"),
				TestElement = (string)configXML.Element("TestElement"),
				ExcludedColumns = configXML.Elements("ExcludedColumns").Any() ? 
								(from ec in configXML.Elements("ExcludedColumns").Elements("Column")
								  select new ExcludedColumn() {
									  DBName = (string)ec.Attribute("DBName")
								  }).ToList() : new List<ExcludedColumn>()
			};

			return dotNailsConfig;
		}

		public XElement SerializeToXml() {
			try {
				// Create new table objects from the table selections
				XElement xml = new XElement("dotNailsConfig",
									new XAttribute("TestAttribute", Config.TestAttribute),
		                            new XElement("TestElement",
										new XAttribute("AnotherAttribute", string.Empty)
		                            ),
									new XElement("ExcludedColumns",
										from excludedColumn in Config.ExcludedColumns
										select new XElement("Column",
											new XAttribute("DBName", excludedColumn.DBName)
										)
		                            )
								);

				return xml;
			}
			catch (Exception ex) {
				throw ex;
			}

		}

		public void SaveToFile() {
			try {
				XElement xml = SerializeToXml();
				FileUtil.CreateFileFromString(_configFilePath, xml.ToString());
			}
			catch (Exception ex) {
				throw (ex);
			}
		}

		public static void CreateEmptyConfigFile(string configFilePath) {
			try {
				// TODO: Create a real namespace
				//XNamespace ns = XNamespace.Get("?");

				// Create the config file
				XElement configXml = new XElement("dotNailsConfig",
										new XAttribute("TestAttribute", "test attribute value"),
										new XElement("TestElement",
											new XAttribute("AnotherAttribute", "testvalue1"),
											"Test element value"
										)
								);

				configXml.Save(configFilePath);
			}
			catch (Exception ex) {
				string text = ex.Message;
			}
		}

		public static string GetConfigFilePath(string solutionFilePath) {
			//string solutionFilePath = dte.Solution.FileName;
			string solutionFolderPath = FileUtil.GetFolderPath(solutionFilePath);

			// Remove extension
			string configFilename = "dotNails." + Path.GetFileNameWithoutExtension(solutionFilePath) + ".config";
			string configFilePath = Path.Combine(solutionFolderPath, configFilename);

			if (!File.Exists(configFilePath)) {
				// Create the config file
				ConfigData.CreateEmptyConfigFile(configFilePath);
			}

			return configFilePath;
		}

	}

	[Serializable]
	public class DotNailsConfig {
		public string TestAttribute { get; set; }
		public string TestElement { get; set; }
		public List<ExcludedColumn> ExcludedColumns;
	}

	[Serializable]
	public class ExcludedColumn {
		public string DBName { get; set; }
	}
}
